{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Dictionary\n",
    "----"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Xem thêm về [Dictionary](https://www.tutorialspoint.com/python/python_dictionary.htm)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![Dictionary](https://lh3.googleusercontent.com/vUkmN64tdZFJ3OzPlMm389Nm5NN_mBQAlSDZ8_MaSwN39nyWqky-qMY-IJzbLBRL97UkB2Unkkt-Ksom1aUY0s2k5RsfOz0Z9J9RFdlYUdCdG19WmWgnu5UsSSpV2e9HUryO6xvroTDb8Ard6spKioV8RYtm9zkBMlS6tC7y-euF7-HWa_nYw8UvQ-K8ZP93Ll3En_E9wlPTttPbNur4_rJfOkz9xUlXyxq3H_JvcDPYeV9Biutitv8MOOLFHqrfSzolrLFrOZKMIQQ5H0OrNLrJZ0YGH97g3ey7jHhKQ6GTjRBnFmsDKTLwwef-ZvB0uZVILYNfI1GN_GEREtibOAc5uYsm3CXSLW9WzAgDiEm7cwp5lrgFAzp1HLaIVqIMoVWYrXToNiDFwfYsQwWu9QXDk2aQcdDo_KlCmyhzhvi69RlWbdDLBOrueWqOT43av32lwGx9AI_mtXT-kRDESDSO_OMlivIxs8CbNkYb53zjxS9wP9PBY3Ntk0L5VZd59der3CTVI9Z9jeqqZWlsr5_tPI_ZG0wEX6cnJ5qvlnXmyyI9sxORmHf5qQutSa6Xa5ahbKXEu_fu7qPbitTyw926l6gE8YOwYrroWuPGAUwL7cR59530Rxbsl37q4wVC_DRyucfeAxDa6JbmtCHfFVnKd5gIL8S83g=w1000-h728-no)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Dictionary trong tiếng Việt là từ điển. Một quyển từ điển sẽ bao gồm nhiều **từ(key)** được diễn giải **ý nghĩa(value)**, dictionary trong python cũng tương tự bao gồm nhiều **cặp key-value**. Key và Value được phân cách nhau bởi dấu hai chấm (:), các cặp key-value được phân cách nhau bởi dấu phẩy (,).\n",
    "\n",
    "Dictionary là kiểu dữ liệu **khả biến(mutable).**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### I. Khởi tạo một Dictionary"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 1. Cách 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "soobin = { \"age\": 26, \"song\": [\"Phia sau mot co gai\"] }"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "sontung = {\n",
    "        \"name\": \"Son Tung MTP\", \n",
    "        \"birth year\": 1994, \n",
    "        \"song\": [ \n",
    "            \"Lac Troi\", \n",
    "            \"Noi nay co anh\", \n",
    "            \"Chung ta khong thuoc ve nhau\"\n",
    "        ],\n",
    "        \"mother\": { \n",
    "            \"name\": \"Pham Thi Thanh Binh\"\n",
    "        }\n",
    "    }"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "adresses = { 1: \"Luong Ngoc Quyen\", 2: \"Xuan Thuy\", 3: \"Cau Giay\" }"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "rooms = { (\"pillows\" , \"carpet\", \"computer\"): \"bedroom\" }"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "###### 2. Cách 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'albums': ['Dong', 'Vet Mua', 'Yeu Xa'], 'name': 'Vu Cat Tuong', 'year': 1992}"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dict([(\"name\", \"Vu Cat Tuong\"), (\"year\", 1992), (\"albums\", [\"Dong\", \"Vet Mua\", \"Yeu Xa\"])])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 3. Cách 3\n",
    "Trong trường hợp các keys đều là chuỗi"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'activities': ['skipping rope',\n",
       "  'playting see-saw',\n",
       "  'swinging',\n",
       "  'flying kite',\n",
       "  'blowing bubbies',\n",
       "  'sliding'],\n",
       " 'type': 'zoo'}"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dict(type=\"zoo\", activities=[\"skipping rope\", \"playting see-saw\", \"swinging\", \"flying kite\", \"blowing bubbies\", \"sliding\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 4. Cách 4"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'Duong': 'Duong dep trai', 'Kien': 'Kien dep trai'}"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "{x: x + \" dep trai\" for x in [\"Duong\", \"Kien\"]}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### II. Kiểu dữ liệu của Key và Value"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Ta có thể kết luận rằng, Kiểu dữ liệu của **key** có thể là bất kỳ kiểu **bất biến(immutable)** nào ví dụ như **chuỗi(string) hay số**, thậm chí **tuple**. \n",
    "\n",
    "Tuple có thể làm key nhưng chỉ trong trường hợp **tuple** đó **chứa** các giá trị bất biến **như chuỗi, số hay tuple.**\n",
    "\n",
    "Kiểu dữ liệu của **value** vô cùng đa dạng có thể là bất cứ kiểu dữ liệu nào"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "unhashable type: 'list'",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-12-9e530ba59a2d>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m      1\u001b[0m \u001b[1;31m# Trường hợp dùng tuple có chứa giá trị khả biến làm key -> xảy ra lỗi\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0mrooms2\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m{\u001b[0m \u001b[1;33m(\u001b[0m\u001b[1;34m\"pillows\"\u001b[0m \u001b[1;33m,\u001b[0m \u001b[1;34m\"carpet\"\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m[\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m\"bedroom\"\u001b[0m \u001b[1;33m}\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m: unhashable type: 'list'"
     ]
    }
   ],
   "source": [
    "# Trường hợp dùng tuple có chứa giá trị khả biến làm key -> xảy ra lỗi\n",
    "rooms2 = { (\"pillows\" , \"carpet\", [] ): \"bedroom\" }"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### III. Truy cập giá trị trong Dictionary\n",
    "\n",
    "    - Trả về value tương ứng với key\n",
    "    - Throw error nếu key không tồn tại"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['Lac Troi', 'Noi nay co anh', 'Chung ta khong thuoc ve nhau']"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Lấy ra danh sách các bài hát của Son Tung\n",
    "sontung[\"song\"]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "ename": "KeyError",
     "evalue": "'born'",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mKeyError\u001b[0m                                  Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-14-3c9a6324381a>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m      1\u001b[0m \u001b[1;31m# Throw error trong trường hợp key born không tồn tại\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0msontung\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m\"born\"\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mKeyError\u001b[0m: 'born'"
     ]
    }
   ],
   "source": [
    "# Throw error trong trường hợp key born không tồn tại\n",
    "sontung[\"born\"]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Tìm tuổi của SooBin"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "26"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "soobin[\"age\"]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'name': 'Pham Thi Thanh Binh'}"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Tìm mẹ của Sơn Tùng\n",
    "sontung[\"mother\"]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Pham Thi Thanh Binh'"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Lấy ra tên bác\n",
    "sontung[\"mother\"][\"name\"]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Trường hợp 2 key giống hệt nhau, khi truy cập các phần tử trong đó ta sẽ thu được value của key cuối cùng."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "Ngoc = {\"name\": \"Nguyen Ba Ngoc\", \"name\": \"John Ngoc\"}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'John Ngoc'"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Ngoc[\"name\"]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['birth year', 'mother', 'name', 'song']"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(sontung)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### IV. Thay đổi Dictionary"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 1. Cập nhật value"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Vì dictionary là **khả biến** nên khi thay đổi giá trị của nó đồng nghĩa với việc thay đổi trực tiếp giá trị trên ô nhớ mà không phải tạo ra một ô nhớ mới."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "ironman = {\"name\": \"Tony Stark\", \"publisher\": \"Unknow\"}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "ironman[\"publisher\"] = \"Marvel Comics\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'name': 'Tony Stark', 'publisher': 'Marvel Comics'}"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ironman"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "ha = { \"name\": \"Ha\", \"name\":\"Alex\"}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "ha[\"name\"] = \"Jeanine\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'name': 'Jeanine'}"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ha"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 2. Xóa đi phần tử"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Xóa đi 1 phần tử"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [],
   "source": [
    "zara = { \"name\": \"Zara\", \"founded\" : 1974, \"revenue\": \"18 billion USD\" }"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [],
   "source": [
    "del zara[\"founded\"]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'name': 'Zara', 'revenue': '18 billion USD'}"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "zara"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Xóa tất cả các phần tử"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "apple= { \"name\": \"Apple\", \"founded\": 1976, \"stock price\": \"$210\" }"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [],
   "source": [
    "apple.clear()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{}"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "apple"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Xóa hẳn Dictionary\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [],
   "source": [
    "PMG = { \"name\": \"PMG\", \"CEO\": \"Jeanie Hood\", \"revenue\": \"110.8 Billion USD\" }"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [],
   "source": [
    "del PMG"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'PMG' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-36-dc0f8ac591c2>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mPMG\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m: name 'PMG' is not defined"
     ]
    }
   ],
   "source": [
    "PMG"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### V. Các phương thức"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 1. keys()\n",
    "Trả về một list tất cả các key của dictionary"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [],
   "source": [
    "ellen = { \"name\": \"Ellen DeGeneres\", \"age\":\"60\", \"title\": [\"comedian\", \"actress\"]}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['age', 'name', 'title']"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ellen.keys()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 2. values()\n",
    "Trả về một list tất cả các value của dictionary"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [],
   "source": [
    "ellen = { \"name\": \"Ellen DeGeneres\", \"age\":\"60\", \"title\": [\"comedian\", \"actress\"]}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['60', 'Ellen DeGeneres', ['comedian', 'actress']]"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ellen.values()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 3. items()\n",
    "Trả về một list các tuple, mỗi tuple chưa cặp key-value"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [],
   "source": [
    "ellen = { \"name\": \"Ellen DeGeneres\", \"age\":\"60\", \"title\": [\"comedian\", \"actress\"]}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[('age', '60'),\n",
       " ('name', 'Ellen DeGeneres'),\n",
       " ('title', ['comedian', 'actress'])]"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ellen.items()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 4. get(key)\n",
    "    - Trả về value của một key\n",
    "    - Trả về None nếu key không tồn tại trong dictionary, không throw Exception"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [],
   "source": [
    "ellen = { \"name\": \"Ellen DeGeneres\", \"age\":\"60\", \"title\": [\"comedian\", \"actress\"]}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'60'"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ellen[\"age\"]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Như tôi đã nhắc đến ở phía trên, nếu key không tồn tại và truy cập bằng cách thông thường, hàm sẽ throw exception"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "ename": "KeyError",
     "evalue": "'wife'",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mKeyError\u001b[0m                                  Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-46-6ad8d45bef5f>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mellen\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m\"wife\"\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mKeyError\u001b[0m: 'wife'"
     ]
    }
   ],
   "source": [
    "ellen[\"wife\"]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Nhưng nếu dùng get thì hàm sẽ không throw exception"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "None\n"
     ]
    }
   ],
   "source": [
    "print(ellen.get(\"wife\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 5. copy()\n",
    "    - Trả về một bản copy nông(shallow) - copy 1 tầng\n",
    "    - dictionary mới được lưu trữ trên một ô nhớ mới (Chỉ đúng trong trường hợp Dictinary 1 tầng)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [],
   "source": [
    "tomcruise = { \"name\": \"Tom Cruise\", \"from\": \"Americe\", \"height\": \"1.7m\"  }"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [],
   "source": [
    "spoof_tomcruise = tomcruise.copy()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'from': 'Americe', 'height': '1.7m', 'name': 'Tom Cruise'}"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "spoof_tomcruise"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Mặc dù giá trị giống nhau nhưng 2 dictionary này được lưu trữ ở ô nhớ khác nhau\n",
    "tomcruise is spoof_tomcruise"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "###### a. copy nông(shallow)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [],
   "source": [
    "phamquynhanh = { \n",
    "    \"name\": \"Pham Quynh Anh\",\n",
    "    \"age\": \"33\", \n",
    "    \"genre\": {\n",
    "        \"name\": \"POP Music\",\n",
    "        \"songs\": [\"One Kiss\", \"Friends\"]\n",
    "    } \n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [],
   "source": [
    "phamquynhanh_copy = phamquynhanh.copy()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'age': '33',\n",
       " 'genre': {'name': 'POP Music', 'songs': ['One Kiss', 'Friends']},\n",
       " 'name': 'Pham Quynh Anh'}"
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "phamquynhanh_copy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 55,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "phamquynhanh_copy is phamquynhanh"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 56,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "phamquynhanh_copy[\"genre\"] is phamquynhanh[\"genre\"]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Các bạn có thể nhận thấy dictionary bên trong - **\"genre\"** vẫn **chưa hoàn toàn** được copy sang một dictionary mới **mà vẫn trỏ** về vị trí ô nhớ ban đầu. Hệ lụy của tính chất này là gì:\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [],
   "source": [
    "phamquynhanh_copy[\"genre\"][\"from\"] = \"mid-1950s\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Đó chính là khi **thay đổi \"genre\"** trong **phamquynhanh_copy** dẫn đến giá trị biến **phamquynhanh** cũng **thay đổi theo**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'age': '33',\n",
       " 'genre': {'from': 'mid-1950s',\n",
       "  'name': 'POP Music',\n",
       "  'songs': ['One Kiss', 'Friends']},\n",
       " 'name': 'Pham Quynh Anh'}"
      ]
     },
     "execution_count": 58,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "phamquynhanh"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Để tránh việc này chúng ta có thể dùng deepcopy để **copy toàn bộ** các tầng của một dictionary sang một dictionary mới hoàn toàn."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "###### b. copy sâu(deep)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [],
   "source": [
    "import copy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [],
   "source": [
    "phamquynhanh = { \n",
    "    \"name\": \"Pham Quynh Anh\",\n",
    "    \"age\": \"33\", \n",
    "    \"genre\": {\n",
    "        \"name\": \"POP Music\",\n",
    "        \"songs\": [\"One Kiss\", \"Friends\"]\n",
    "    } \n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [],
   "source": [
    "phamquynhanh_deep_copy = copy.deepcopy(phamquynhanh)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [],
   "source": [
    "phamquynhanh_deep_copy[\"genre\"][\"from\"] = \"mid-1950s\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'age': '33',\n",
       " 'genre': {'from': 'mid-1950s',\n",
       "  'name': 'POP Music',\n",
       "  'songs': ['One Kiss', 'Friends']},\n",
       " 'name': 'Pham Quynh Anh'}"
      ]
     },
     "execution_count": 63,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "phamquynhanh_deep_copy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'age': '33',\n",
       " 'genre': {'name': 'POP Music', 'songs': ['One Kiss', 'Friends']},\n",
       " 'name': 'Pham Quynh Anh'}"
      ]
     },
     "execution_count": 64,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "phamquynhanh"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Các bạn có thể nhận ra biến **phamquynhanh_deep_copy không còn phụ thuộc** bất cứ thuộc tính nào vào biến **phamquynhanh ban đầu** và ngược lại."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### VI. Các hàm"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 1. len()\n",
    "Trả về số lượng phần tử trong dictionary"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "selena = { \"name\": \"Selena Gomez\", \"age\": 26, \"height\": \"1m65\" }"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(selena)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 2. for in"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "age - 26\n",
      "name - Selena Gomez\n",
      "height - 1m65\n"
     ]
    }
   ],
   "source": [
    "for key in selena:\n",
    "    print \"%s - %s\"%(key, selena[key])"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.14"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
